﻿#include <QIcon>
#include <QFile>
#include <QMessageBox>
#include <QJsonDocument>
#include "mainwindow.h"
#include "ui_mainwindow.h"

//构造函数
MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);

    setWindowTitle("TCP端口转发服务器");
    m_nowSelectListenPort = 0;

    model = new QStandardItemModel(ui->forwardListView);
    model->setHorizontalHeaderLabels(QStringList()<<QStringLiteral("转发列表"));
    ui->forwardListView->setModel(model);

    initForwardSvrList();
    this->setProperty("canMove", true);
    ui->actionStart->setEnabled(true);
    ui->actionStop->setEnabled(false);
    ui->forwardListView->expandAll();
}

//析构函数
MainWindow::~MainWindow()
{
    delete ui;
}

//创建转发服务项参数结构
forwardParaSt * MainWindow::creatForwardSvr(int listenPort, QString toIp, int toPort)
{
    QString name;

    forwardParaSt *pforwardPara = new forwardParaSt;
    pforwardPara->listenPort = listenPort;
    pforwardPara->toIp = toIp;
    pforwardPara->toPort = toPort;
    name=QString("%1->%2:%3").arg(pforwardPara->listenPort).arg(pforwardPara->toIp).arg(pforwardPara->toPort);
    pforwardPara->itemProject = new QStandardItem(QIcon(QStringLiteral(":/icon/connection.png")),name);
    pforwardPara->itemProject->setEditable(false);
    return pforwardPara;
}


//从配置文件中，初始化转发服务列表
void MainWindow::initForwardSvrList()
{
    forwardParaSt *pforwardPara = NULL;
    CTaskService *pTmpTaskSer = NULL;
    CDataWidget  *pDataWidget = NULL;

    QFile CfgFile(config_file);

    CfgFile.open(QIODevice::ReadOnly);
    QByteArray cfgData = CfgFile.readAll();

    QJsonParseError jsonError;//Qt5新类
    QJsonDocument json = QJsonDocument::fromJson(cfgData, &jsonError);//Qt5新类
    if ( jsonError.error != QJsonParseError::NoError )
    {
        ui->msg->setText("json file init fault!");
        return;
    }

    QJsonObject rootObj = json.object();
    if (rootObj.contains("svr"))
    {
        QJsonValue valueArray = rootObj.value("svr");
        QJsonArray jsonArray = valueArray.toArray();

        for (int i = 0; i < jsonArray.count();i++)
        {
            QJsonObject  childObject = jsonArray[i].toObject();
            int listenPort  = childObject.value("listenPort").toInt();
            QString toSvrIp = childObject.value("toSvrIp").toString();
            int toSvrPort   = childObject.value("toSvrPort").toInt();

            pforwardPara = creatForwardSvr(listenPort, toSvrIp, toSvrPort);
            m_forwardList[listenPort] = pforwardPara;

            pTmpTaskSer = new CTaskService(pforwardPara);
            m_TaskServiceList[pforwardPara->itemProject->text()] = pTmpTaskSer;
            connect(pTmpTaskSer, &CTaskService::removeClient, this, &MainWindow::removeClientItem);
            connect(pTmpTaskSer, &CTaskService::addClient, this, &MainWindow::addClientItem);

            pDataWidget = new CDataWidget;
            pDataWidget->hide();
            pDataWidget->setName(pforwardPara->itemProject->text());
            connect(pTmpTaskSer, &CTaskService::sendLocalClientData, pDataWidget, &CDataWidget::onRecvDevData);
            connect(pTmpTaskSer, &CTaskService::sendSvrClientData, pDataWidget, &CDataWidget::onRecvSvrData);
            connect(pDataWidget, &CDataWidget::sigSendToDevice, pTmpTaskSer, &CTaskService::onSendToDevice);
            connect(pDataWidget, &CDataWidget::sigSendToServer, pTmpTaskSer, &CTaskService::onSendToServer);

            m_devWidgetMap[pforwardPara->itemProject->text()] = pDataWidget;
            ui->mainLayout->addWidget(pDataWidget);
            //pTmpTaskSer->startService();

            model->appendRow(m_forwardList[listenPort]->itemProject);

        }
    }

    return ;
}

//添加转发任务到配置文件中
void MainWindow::addForwardSvrToConfig(int listenPort, QString toSvrIp, int toSvrPort)
{
    QFile CfgFile(config_file);
    CfgFile.open(QIODevice::ReadOnly);
    QByteArray cfgData = CfgFile.readAll();
    CfgFile.close();

    QJsonParseError jsonError;//Qt5新类
    QJsonDocument json = QJsonDocument::fromJson(cfgData, &jsonError);//Qt5新类
    if ( jsonError.error != QJsonParseError::NoError )
    {
        ui->msg->setText("json file init fault!");
        //return;
    }

    QJsonObject jNode;
    jNode.insert("listenPort", QJsonValue(listenPort));
    jNode.insert("toSvrIp", QJsonValue(toSvrIp));
    jNode.insert("toSvrPort", QJsonValue(toSvrPort));


    QJsonObject rootObj = json.object();
    QJsonArray jsonArray;
    if (rootObj.contains("svr"))
    {
        jsonArray = rootObj.value("svr").toArray();
    }

    jsonArray.append(jNode);
    rootObj.insert("svr", jsonArray);

    qDebug()<<"jsonArray: "<<QJsonDocument(rootObj).toJson();

    CfgFile.open(QIODevice::WriteOnly);
    CfgFile.write(QJsonDocument(rootObj).toJson());
    CfgFile.close();
}

//删除指定端口的转发服务项，并回写配置
void MainWindow::delForwardSvrToConfig(int listenPort)
{
    QFile CfgFile(config_file);
    CfgFile.open(QIODevice::ReadOnly);
    QByteArray cfgData = CfgFile.readAll();
    CfgFile.close();

    QJsonParseError jsonError;//Qt5新类
    QJsonDocument json = QJsonDocument::fromJson(cfgData, &jsonError);//Qt5新类
    if ( jsonError.error != QJsonParseError::NoError )
    {
        ui->msg->setText("json file init fault!");
        return;
    }

    QJsonObject rootObj = json.object();
    if (rootObj.contains("svr"))
    {
        QJsonArray jsonArray = rootObj.value("svr").toArray();

        for (int i = 0; i < jsonArray.count();i++)
        {
            QJsonObject  childObject = jsonArray[i].toObject();
            if ( childObject.value("listenPort").toInt() == listenPort )
            {
                jsonArray.removeAt(i);
                break;
            }
        }

        rootObj.insert("svr", jsonArray);

        CfgFile.open(QIODevice::WriteOnly);
        CfgFile.write(QJsonDocument(rootObj).toJson());
        CfgFile.close();
    }
}


//获取父节点
QModelIndex MainWindow::getTopParent(const QModelIndex &itemIndex)
{
    QModelIndex secondItem = itemIndex;
    QModelIndex tmp = itemIndex;
    while(tmp.parent().isValid())
    {
        secondItem = tmp.parent();
        tmp = secondItem;
        qDebug()<<"now text: "<<secondItem.data().toString();
    }

    return secondItem;
}

//设置显示区域显示指定连接的交互数据
void MainWindow::selectPrintData(QString name, int id)
{
    if ( !nowPrintDataSerivice.isEmpty() )
    {
        QMap<QString,CTaskService*>::iterator iter = m_TaskServiceList.find(nowPrintDataSerivice);
        if ( iter != m_TaskServiceList.end() )
        {
            iter.value()->stopPrintData();
        }
    }

    m_TaskServiceList[name]->setSelectId(id);
    nowPrintDataSerivice = name;
}

//单击转发列表事件处理
void MainWindow::on_forwardListView_clicked(const QModelIndex &index)
{
    QString str;
    str += QStringLiteral("当前选中：%1 row:%2,column:%3 ").arg(index.data().toString())
                          .arg(index.row()).arg(index.column());
    QString bakLaskItem = m_nowSelectItem; // 上一次选中的条目
    m_nowSelectItem = getTopParent(index).data().toString();
    m_nowSelectListenPort = m_nowSelectItem.left(m_nowSelectItem.indexOf("->")).toInt();
    qDebug()<<"selected: "<<m_nowSelectItem<<", listen port: "<<m_nowSelectListenPort;
    ui->msg->setText(str);

    m_nowSelectSvrRow = index;

    if ( bakLaskItem != m_nowSelectItem )
    {
        auto iter = m_devWidgetMap.find(bakLaskItem);//隐藏原来的
        if ( iter != m_devWidgetMap.end() )
        {
            iter.value()->hide();
        }

        iter = m_devWidgetMap.find(m_nowSelectItem);//显示当前选中
        if ( iter != m_devWidgetMap.end() )
        {
            iter.value()->show();
        }
    }

    if(m_nowSelectItem,index.data().toString() != m_nowSelectItem)
        selectPrintData(m_nowSelectItem,index.data().toString().toInt());
}

//启动服务按钮
void MainWindow::on_actionStart_triggered()
{
    ui->msg->setText("start service");
    ui->actionStart->setEnabled(false);
    ui->actionStop->setEnabled(true);
    ui->actionAdd->setEnabled(false);
    ui->actionDel->setEnabled(false);
    ui->actionmdify->setEnabled(false);

    QMap<QString,CTaskService*>::iterator iter;
    for ( iter = m_TaskServiceList.begin(); iter != m_TaskServiceList.end(); iter++)
    {
        iter.value()->startService();
        qDebug()<<"start "<<iter.key();
    }

}

//停止服务按钮处理
void MainWindow::on_actionStop_triggered()
{
    ui->msg->setText("stop service");
    ui->actionStart->setEnabled(true);
    ui->actionStop->setEnabled(false);
    ui->actionAdd->setEnabled(true);
    ui->actionDel->setEnabled(true);
    ui->actionmdify->setEnabled(true);

    QMap<QString,CTaskService*>::iterator iter;

    for ( iter = m_TaskServiceList.begin(); iter != m_TaskServiceList.end(); iter++)
    {
        iter.value()->stopService();
    }

}

//调出添加转发项对话框
void MainWindow::on_actionAdd_triggered()
{
    Dialog setDialog;
    connect(&setDialog, &Dialog::sigAddItem, this, &MainWindow::recvAddSvrPara);
    setDialog.exec();
}

void MainWindow::recvAddSvrPara(svrParaSt &SvrPara)
{
    forwardParaSt *pforwardPara = NULL;
    CTaskService *pTmpTaskSer = NULL;
    CDataWidget  *pDataWidget = NULL;


    QMap<int,forwardParaSt*>::iterator iter = m_forwardList.find(SvrPara.listenPort.toInt());
    if ( iter != m_forwardList.end() ) //already exist
    {
        QMessageBox::warning(this, tr("forwardSvr warning"),
                                       (SvrPara.listenPort+tr(" 已经存在\n")),
                                       QMessageBox::Ok );
        return;
    }

    pforwardPara = creatForwardSvr(SvrPara.listenPort.toInt(), SvrPara.toSvrIp, SvrPara.toSvrPort.toInt());
    m_forwardList[SvrPara.listenPort.toInt()] = pforwardPara;

    pTmpTaskSer = new CTaskService(pforwardPara);
    m_TaskServiceList[pforwardPara->itemProject->text()] = pTmpTaskSer;
    connect(pTmpTaskSer, &CTaskService::removeClient, this, &MainWindow::removeClientItem);
    connect(pTmpTaskSer, &CTaskService::addClient, this, &MainWindow::addClientItem);

    pDataWidget = new CDataWidget;
    pDataWidget->hide();
    pDataWidget->setName(pforwardPara->itemProject->text());
    connect(pTmpTaskSer, &CTaskService::sendLocalClientData, pDataWidget, &CDataWidget::onRecvDevData);
    connect(pTmpTaskSer, &CTaskService::sendSvrClientData, pDataWidget, &CDataWidget::onRecvSvrData);
    connect(pDataWidget, &CDataWidget::sigSendToDevice, pTmpTaskSer, &CTaskService::onSendToDevice);
    connect(pDataWidget, &CDataWidget::sigSendToServer, pTmpTaskSer, &CTaskService::onSendToServer);

    m_devWidgetMap[pforwardPara->itemProject->text()] = pDataWidget;
    ui->mainLayout->addWidget(pDataWidget);

    if (!ui->actionStart->isEnabled())
       pTmpTaskSer->startService();

    model->appendRow(m_forwardList[SvrPara.listenPort.toInt()]->itemProject);
    addForwardSvrToConfig(SvrPara.listenPort.toInt(), SvrPara.toSvrIp, SvrPara.toSvrPort.toInt());
}

//删除转发服务项
void MainWindow::on_actionDel_triggered()
{
    if ( QMessageBox::Cancel == QMessageBox::question(this, "询问?" , QString("是否要删除任务[%1]").arg(m_nowSelectItem), QMessageBox::Ok, QMessageBox::Cancel))
    {
        return;
    }

    QString forwardName = m_nowSelectSvrRow.data().toString();

    QMap<int,forwardParaSt*>::iterator iter = m_forwardList.find(m_nowSelectListenPort);
    if ( iter != m_forwardList.end() )
    {
        qDebug()<<"del "<<m_nowSelectListenPort<<" para";
        delete iter.value();
        m_forwardList.erase(iter);

    }

    QMap<QString,CTaskService*>::iterator iter1 = m_TaskServiceList.find(forwardName);
    if ( iter1 != m_TaskServiceList.end() )
    {
        qDebug()<<"del "<<forwardName;
        delete iter1.value();
        m_TaskServiceList.erase(iter1);
    }

    QMap<QString,CDataWidget*>::iterator iterDevWidget = m_devWidgetMap.find(forwardName);
    if ( iterDevWidget != m_devWidgetMap.end() )
    {
        qDebug()<<"del widget "<<forwardName;
        ui->mainLayout->removeWidget(iterDevWidget.value()); // 从layout中移除
        delete iterDevWidget.value();
        m_devWidgetMap.erase(iterDevWidget);
    }

    model->removeRow(m_nowSelectSvrRow.row());
    delForwardSvrToConfig(m_nowSelectListenPort);
}

//移除显示的连接列表
void MainWindow::removeItem(int id,QStandardItem *&svrItem)
{
    QStandardItem *ptmpItem = svrItem;

    ptmpItem = ptmpItem->child(0);

    while(ptmpItem)
    {
        if ( id == ptmpItem->text().toInt() )
        {
            qDebug()<<"find "<<id<<", row: "<<ptmpItem->index().row()<<" client, now remove";
            svrItem->removeRow( ptmpItem->index().row());
            break;
        }
        else
        {
            ptmpItem = svrItem->child(ptmpItem->row()+1);
            if(ptmpItem)
                qDebug()<<"get child id: "<<ptmpItem->text();
        }
    }
}

//修改任务
void MainWindow::on_actionmdify_triggered()
{
    if ( m_nowSelectListenPort == 0 )
        return;
    forwardParaSt *pstPara = m_forwardList[m_nowSelectListenPort];

    Dialog setDialog;
    connect(&setDialog, &Dialog::sigModifyItem, this, &MainWindow::recvModifySvrPara);
    setDialog.setValue(QString::number(m_nowSelectListenPort), pstPara->toIp, QString::number(pstPara->toPort));
    setDialog.exec();
}

//修改
void MainWindow::recvModifySvrPara(svrParaSt &SvrPara)
{
    forwardParaSt *pforwardPara = NULL;
    CTaskService *pTmpTaskSer = NULL;
    CDataWidget  *pDataWidget = NULL;

    auto iterPara = m_forwardList.find(m_nowSelectListenPort);
    if ( iterPara != m_forwardList.end())
    {
        delete iterPara.value();
    }
    m_forwardList.remove(m_nowSelectListenPort);

    auto iter = m_TaskServiceList.find(m_nowSelectItem);
    if ( iter != m_TaskServiceList.end())
    {
        delete iter.value();
    }

    m_TaskServiceList.remove(m_nowSelectItem);
    auto pDevWidget = m_devWidgetMap[m_nowSelectItem];
    ui->mainLayout->removeWidget(pDevWidget);
    delete pDevWidget;

    delForwardSvrToConfig(m_nowSelectListenPort);      //删除配置里的数据

    //重新创建新的对象
    pforwardPara = creatForwardSvr(SvrPara.listenPort.toInt(), SvrPara.toSvrIp, SvrPara.toSvrPort.toInt());
    m_forwardList[SvrPara.listenPort.toInt()] = pforwardPara;

    pTmpTaskSer = new CTaskService(pforwardPara);
    m_TaskServiceList[pforwardPara->itemProject->text()] = pTmpTaskSer;
    connect(pTmpTaskSer, &CTaskService::removeClient, this, &MainWindow::removeClientItem);
    connect(pTmpTaskSer, &CTaskService::addClient, this, &MainWindow::addClientItem);

    pDataWidget = new CDataWidget;
    pDataWidget->hide();
    pDataWidget->setName(pforwardPara->itemProject->text());
    connect(pTmpTaskSer, &CTaskService::sendLocalClientData, pDataWidget, &CDataWidget::onRecvDevData);
    connect(pTmpTaskSer, &CTaskService::sendSvrClientData, pDataWidget, &CDataWidget::onRecvSvrData);
    connect(pDataWidget, &CDataWidget::sigSendToDevice, pTmpTaskSer, &CTaskService::onSendToDevice);
    connect(pDataWidget, &CDataWidget::sigSendToServer, pTmpTaskSer, &CTaskService::onSendToServer);

    m_devWidgetMap[pforwardPara->itemProject->text()] = pDataWidget;
    ui->mainLayout->addWidget(pDataWidget);

    if (!ui->actionStart->isEnabled())
       pTmpTaskSer->startService();

    model->setItem(m_nowSelectSvrRow.row(),m_nowSelectSvrRow.column(), pforwardPara->itemProject);
    addForwardSvrToConfig(SvrPara.listenPort.toInt(), SvrPara.toSvrIp, SvrPara.toSvrPort.toInt());
}

//移除指定客户端连接显示列表
void MainWindow::removeClientItem(int port, int id)
{
    QMap<int,forwardParaSt*>::iterator iter = m_forwardList.find(port);
    if ( iter != m_forwardList.end() )
    {
        removeItem(id, iter.value()->itemProject);
        qDebug()<<"del "<<port<<" id: "<<id;
    }
}

//添加新连接转发列表
void MainWindow::addClientItem(int port, int id)
{
    QMap<int,forwardParaSt*>::iterator iter = m_forwardList.find(port);
    if ( iter != m_forwardList.end() )
    {
        QString name = QString("%1").arg(id);
        QStandardItem* subItem = new QStandardItem(QIcon(QStringLiteral(":/icon/disconnect.png")),name);
        subItem->setEditable(false);
        iter.value()->itemProject->appendRow(subItem);
        qDebug()<<"add "<<port<<" id: "<<id;

        ui->forwardListView->expand(iter.value()->itemProject->index());
    }
}

//帮助。about
void MainWindow::on_actionAbout_triggered()
{
    QMessageBox::about(this, "about", tr("TCP端口转发监控服务器    \n"
                                         "Email    :  fensnote@163.com\n"
                                         "Author  :  fensnote\n"
                                         "Ver       :  V2.0.0\n"
                                         ));

}


